/**
 * Licensed under the MIT License
 *
 * Copyright (c) 2012 Gary Paluk, http://www.plugin.io
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

package io.plugin.blib.gui 
{
	import flash.display.Bitmap;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import io.plugin.blib.gfx.BlibEntity;
	import io.plugin.blib.gfx.BlibDisplay;
	import io.plugin.blib.gui.widgets.BlibWidgetCollection;
	import io.plugin.collections.IIterator;
	import io.plugin.collections.list.ListIterator;
	import org.osflash.signals.natives.NativeSignal;
	
	/**
	 * ...
	 * @author Gary Paluk - http://www.plugin.io
	 */
	// Abstract class
	// TODO enforce abstraction
	public class BlibWidget extends BlibEntity 
	{
		
		private var _parent: BlibWidget;
		private var _children: BlibWidgetCollection;
		private var _focusable: Boolean;
		
		public var mouseMotion: NativeSignal;
		
		public function BlibWidget() 
		{
			super.isWorldObject = false;
			_children = new BlibWidgetCollection();
			_focusable = true;
			
			mouseMotion = new NativeSignal( BlibDisplay.getInstance().stage, MouseEvent.MOUSE_MOVE, MouseEvent );
			mouseMotion.add( onMouseMotion );
		}
		
		public function get parent():BlibWidget 
		{
			return _parent;
		}
		
		public function hasFocus(): Boolean
		{
			// TODO implement this
			return false;
		}
		
		override public function draw():void 
		{
			if ( visible )
			{
				var iterator: IIterator = _children.iterator();
				while ( iterator.hasNext() )
				{
					BlibWidget( iterator.next() ).draw();
				}
			}
		}
		
		public function get absoluteRectangle(): Rectangle
		{
			return new Rectangle( absoluteX, absoluteY, width, height );
		}
		
		public function set absoluteRectangle( value: Rectangle ): void
		{
			absoluteX = value.x;
			absoluteY = value.y;
			width = value.width;
			height = value.height;
		}
		
		public function get absoluteLocation(): Point
		{
			return new Point( absoluteX, absoluteY );
		}
		
		public function set absoluteLocation( value: Point ): void
		{
			absoluteX = value.x;
			absoluteY = value.y;
		}
		
		override public function update():void 
		{
			super.update();
			var iterator: IIterator = _children.iterator();
				while ( iterator.hasNext() )
			{
				BlibWidget( iterator.next() ).draw();
			}
		}
		
		public function set parent(value:BlibWidget):void 
		{
			if ( _parent != null )
			{
				if ( _parent.children.contains( this ) )
				{
					_parent.children.remove( this );
				}
				_parent = value;
				if ( _parent != null )
				{
					if ( !_parent.children.contains( this ) )
					{
						_parent.children.add( this );
					}
				}
			}
		}
		
		public function get children():BlibWidgetCollection		
		{
			return _children;
		}
		
		public function add( widget: BlibWidget ): void
		{
			_children.add( widget );
			widget.parent = this;
		}
		
		public function get focusable():Boolean 
		{
			return _focusable;
		}
		
		public function set focusable(value:Boolean):void 
		{
			_focusable = value;
		}
		
		public function get absoluteX(): Number
		{
			if ( _parent != null )
			{
				return _parent.absoluteX + this.x;
			}
			else
			{
				return this.x;
			}
		}
		
		public function set absoluteX( value: Number ): void
		{
			if ( _parent != null )
			{
				this.x = value - _parent.absoluteX;
			}
			else
			{
				this.x = value;
			}
		}
		
		
		
		public function get absoluteY(): Number
		{
			if ( _parent != null )
			{
				return _parent.absoluteY + this.y;
			}
			else
			{
				return this.y;
			}
		}
		
		public function set absoluteY( value: Number ): void
		{
			if ( _parent != null )
			{
				this.y = value - _parent.absoluteY;
			}
			else
			{
				this.y = value;
			}
		}
		
		// TODO handle widget events
		public function onMouseMotion( e: MouseEvent ): void
		{
			var stage: Stage = BlibDisplay.getInstance().stage as Stage;
			
			
			var iterator: IIterator = _children.iterator();
			while ( iterator.hasNext() )
			{
				
				var widget: BlibWidget = iterator.next()
				if ( widget.absoluteRectangle.intersects( new Rectangle( e.stageX, e.stageY, 1, 1 ) ) )
				{
					trace( "hi" );
					
					widget.onMouseMotion( e );
				}
			}
		}
		
	}

}